package cc.verywell.pureblock.msg.nfs.idx;
/**
* 文件总索引结构
* Copyright © 2019 TanYaqiu. All rights reserved.
* @author TanYaqiu 
* @address flat 601
* @date 2019年10月2日 下午1:00:06
*/

import java.nio.ByteBuffer;
import java.util.Arrays;

import cc.verywell.pureblock.msg.nfs.strc.EncodeAble;
import cc.verywell.pureblock.util.StringUtil;

public class NfsidxStructure implements EncodeAble {
	private static final byte IS_EXTERNAL = 0b001;
	private static final byte IS_PARTFILE = 0b010;
	private static final byte IS_PUREDATA = 0b100;
	public static  final int OFFSET_MOVE = 20;
	public static  final long OFFSET_CHECK = -1L<<Long.SIZE-OFFSET_MOVE;
	public static  final long SIZE_MARK = -1L>>>Long.SIZE-OFFSET_MOVE;
	
	private byte[] payload;
	
	protected NfsidxStructure(NfsidxStructure old) {
		this.payload = old.payload;
	}
	public NfsidxStructure(byte[] payload) {
		this.payload = payload;
	}
	public NfsidxStructure(boolean isExternal,boolean isPuredata,byte[] path,long size) {
		if(size != (size & SIZE_MARK))throw new IllegalArgumentException(path+" size: "+size+" too big.");
		payload = new byte[path.length+1+8];
		ByteBuffer b = ByteBuffer.wrap(payload);
		b.put((byte)( (isExternal?IS_EXTERNAL:0) | (isPuredata?IS_PUREDATA:0) ));
		b.put(path);
		b.putLong(size);
	}
	public NfsidxStructure(boolean isExternal,boolean isPuredata,byte[] path,long offset,long size) {
		if(0 != (offset & OFFSET_CHECK) || size != (size & SIZE_MARK))throw new IllegalArgumentException(path+" offset: "+offset+" size: "+size+" too big.");
		payload = new byte[path.length+1+8];
		ByteBuffer b = ByteBuffer.wrap(payload);
		b.put((byte)(IS_PARTFILE | (isExternal?IS_EXTERNAL:0) | (isPuredata?IS_PUREDATA:0) ));
		b.put(path);
		b.putLong((offset << OFFSET_MOVE) | size);
	}
	
	public boolean isExternal() {
		return 0 != (IS_EXTERNAL & payload[0]);
	}
	public boolean isPartfile() {
		return 0 != (IS_PARTFILE & payload[0]);
	}
	public boolean isPuredata() {
		return 0 != (IS_PUREDATA & payload[0]);
	}
	public String getPath() {
		return StringUtil.byteToString(payload,1,payload.length-9);
	}
	public long getOffset() {
		ByteBuffer b = ByteBuffer.wrap(payload,payload.length-8,8);
		long l = b.getLong();
		return l>>>OFFSET_MOVE;
	}
	public long getSize() {
		ByteBuffer b = ByteBuffer.wrap(payload,payload.length-8,8);
		long l = b.getLong();
		return l & SIZE_MARK;
	}
	
	@Override
	public int encodeSize() {
		return payload.length;
	}
	@Override
	public void encode(ByteBuffer bb) {
		bb.put(payload);
	}
	
	@Override
	public int hashCode() {
		return Arrays.hashCode(payload);
	}
	@Override
	public boolean equals(Object obj) {
		if(obj==null || !this.getClass().equals(obj.getClass()))return false;
		return Arrays.equals(this.payload, ((NfsidxStructure)obj).payload );
	}
	@Override
	public String toString() {
		return (isExternal()?"External:":"Internal:")+
				(isPuredata()?"OnlyData:":"FullBag:")+
				getPath()+
				(isPartfile()?(" ["+getOffset()+"-"+getSize()+"]"):("["+getSize()+"]"));
	}
	
	
}
